use tweeny_rpc::{macros::rpc_service, utils::helper_types::*};

#[rpc_service(both_sides, static_ref_all_under_surface_solve(resp))]
trait CoolServ {
    async fn proc1(
        &self,
        name: &'static str,
        number: usize,
    ) -> (DeserRefSrcBoxedBytes, &'static str);
    async fn proc2(
        &self,
        x: usize,
        b: (&'static [u8], DeserRefSrcArcBytes),
    ) -> Result<(f64, &'static str), ()>;
    async fn proc3(&self, a: [u8; 10]);
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    use std::net::SocketAddr;
    use std::{str::FromStr, sync::Arc};
    use tweeny_rpc::{client::with_default_serder_tcp, server::Server};

    struct CoolServer;
    #[allow(unused)]
    impl CoolServ for CoolServer {
        type OtherEndInfo = SocketAddr;
        fn proc1(
            &self,
            from: Self::OtherEndInfo,
            name: &'static str,
            number: usize,
        ) -> impl Future<Output = (DeserRefSrcBoxedBytes, &'static str)> + Send {
            async move { todo!() }
        }
        fn proc2(
            &self,
            from: Self::OtherEndInfo,
            x: usize,
            b: (&'static [u8], DeserRefSrcArcBytes),
        ) -> impl Future<Output = Result<(f64, &'static str), ()>> + Send {
            async move { todo!() }
        }
        fn proc3(&self, from: Self::OtherEndInfo, a: [u8; 10]) -> impl Future<Output = ()> + Send {
            async move { todo!() }
        }
    }

    let addr = SocketAddr::from_str("127.0.0.1:22330").unwrap();
    let serv =
        Server::with_default_serder_tcp(Arc::new(CoolServServerWrapper(CoolServer)), addr).await?;
    tokio::spawn(serv.serve());

    let (client_serv, client_handle) = with_default_serder_tcp(addr).await?;
    tokio::spawn(client_serv);
    let client_handle = CoolServReqHandle(client_handle);
    let _ = client_handle.proc3([0u8; 10], None).await;
    Ok(())
}
